#ifndef _CPP_STORY_HELPER_H_
#define _CPP_STORY_HELPER_H_

#include <sstream>
#include <stdexcept>
#include <string>
#include "background.h"
#include "examples.h"
#include "feature.h"
#include "scenario.h"
#include "step.h"
#include "table.h"
#include "world.h"

namespace CppStory
{

class FeatureRegisterHelper
{
public:
    FeatureRegisterHelper(Feature* feature)
    {
        World::instance()->register_feature(feature);
    }
};

class InOrderHelper
{
public:
    InOrderHelper(const char* in_order)
    {
        World::instance()->get_cur_feature()->set_in_order(in_order);
    }
};

class AsHelper
{
public:
    AsHelper(const char* as)
    {
        World::instance()->get_cur_feature()->set_who(as);
    }
};

class IWantHelper
{
public:
    IWantHelper(const char* want)
    {
        World::instance()->get_cur_feature()->set_want(want);
    }
};

class ScenarioRegisterHelper
{
public:
    ScenarioRegisterHelper(Scenario* scenario)
    {
        World::instance()->get_cur_feature()->register_scenario(scenario);
    }
};

class ScenarioNameHelper
{
public:
    ScenarioNameHelper(const char* n)
    {
        World::instance()->get_cur_feature()->get_cur_scenario()->set_name(n);
    }
};

class StepRegisterHelper
{
public:
    StepRegisterHelper(Step* step)
    {
        if (NULL == World::instance()->get_cur_feature()->get_cur_scenario())
            World::instance()->get_cur_feature()->get_background()->register_step(step);
        else
            World::instance()->get_cur_feature()->get_cur_scenario()->register_step(step);
    }
};

class StepNameHelper
{
public:
    StepNameHelper(const char* n)
    {
        if (NULL == World::instance()->get_cur_feature()->get_cur_scenario())
            World::instance()->get_cur_feature()->get_background()->get_cur_step()->set_name(n);
        else
            World::instance()->get_cur_feature()->get_cur_scenario()->get_cur_step()->set_name(n);
    }
};

class StepDefinitionRegisterHelper
{
public:
    StepDefinitionRegisterHelper(StepDefinition* step_definition)
    {
        World::instance()->register_step_def(step_definition);
    }
};

template<typename T>
T FromString(const std::string& s)
{
    std::istringstream stream(s);
    T t;
    stream >> t;
    if (stream.fail())
    {
        throw std::invalid_argument("Cannot convert parameter");
    }
    return t;
}

class TableCreateHelper
{
public:
    TableCreateHelper()
    {
        World::instance()->get_cur_feature()->get_cur_scenario()->get_cur_step()->create_table();
    }
};

class TableStrHelper
{
public:
    TableStrHelper(const char* s)
    {
        World::instance()->get_cur_feature()->get_cur_scenario()->get_cur_step()->get_table()->set_str(s);
        World::instance()->get_cur_feature()->get_cur_scenario()->get_cur_step()->get_table()->parse();
    }
};

class ExamplesCreateHelper
{
public:
    ExamplesCreateHelper()
    {
        World::instance()->get_cur_feature()->get_cur_scenario()->create_examples();
    }
};

class ExamplesTableStrHelper
{
public:
    ExamplesTableStrHelper(const char* s)
    {
        World::instance()->get_cur_feature()->get_cur_scenario()->get_examples()->get_table()->set_str(s);
        World::instance()->get_cur_feature()->get_cur_scenario()->get_examples()->get_table()->parse();
    }
};

class BackgroundCreateHelper
{
public:
    BackgroundCreateHelper()
    {
        World::instance()->get_cur_feature()->create_background();
    }
};

}

#endif

